﻿using RockBus.Logging.Interfaces;
using RockBus.Transport.Interfaces;
using System;
using System.Reflection;
using System.ServiceModel.Channels;
using System.Threading.Tasks;
using System.Transactions;

namespace RockBus.Transport.Wcf
{
    public class TransportOneWay : ITransport
    {
        public TransportOneWay(ILogger logger, IOneWay client, MessageVersion messageVersion)
        {
            this.Logger = logger;
            this.Client = client;
            this.MessageVersion = messageVersion;
        }

        private ILogger Logger { get; set; }

        private IOneWay Client { get; set; }

        public MessageVersion MessageVersion { get; private set; }

        public Task<Message> StartTransportMessage(Message message)
        {
            CallContext<IOneWay> cc = new CallContext<IOneWay>()
            {
                Client = ((OneWayClient)this.Client).Contract,
            };

            this.Logger.LogDebug(MethodBase.GetCurrentMethod(), "Transporting message with action {0}", message.Headers.Action);
            this.Logger.Log(MethodBase.GetCurrentMethod(), LogLevelEnum.Debug, Transaction.Current);

            var task = Task<Message>.Factory.FromAsync(
                this.Client.BeginProcessMessage,
                this.EndProcessMessage,
                message,
                cc,
                TaskCreationOptions.AttachedToParent);

            return task;
        }

        private Message EndProcessMessage(IAsyncResult asyncResult)
        {
            Logger.Log(MethodBase.GetCurrentMethod(), LogLevelEnum.Debug, Transaction.Current);
            CallContext<IOneWay> cc = asyncResult.AsyncState as CallContext<IOneWay>;
            cc.Client.EndProcessMessage(asyncResult);
            return null;
        }
    }
}